package com.piggy.logi.sys.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.web.page.PagePlus;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.logi.sys.api.domain.LogiSysDept;
import com.piggy.logi.sys.bo.LogiBranchBusStatisticsQueryBo;
import com.piggy.logi.sys.bo.LogiCustomerBusStatisticsQueryBo;
import com.piggy.logi.sys.bo.LogiProjectBusStatisticsQueryBo;
import com.piggy.logi.sys.bo.LogiTransportBusStatisticsQueryBo;
import com.piggy.logi.sys.domain.*;
import com.piggy.logi.sys.enums.DeptTypeEnum;
import com.piggy.logi.sys.service.*;
import com.piggy.logi.sys.vo.LogiBranchBusStatisticsVo;
import com.piggy.logi.sys.vo.LogiCustomerBusStatisticsVo;
import com.piggy.logi.sys.vo.LogiProjectBusStatisticsVo;
import com.piggy.logi.sys.vo.LogiTransportBusStatisticsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 业务统计Service业务层处理
 *
 * @author fengxy
 * @date 2023/10/17 21:54
 **/
@Slf4j
@Service
public class LogiBusinessStatisticsServiceImpl implements ILogiBusinessStatisticsService {

    @Resource
    private ILogiCustomerService logiCustomerService;

    @Resource
    private ILogiWaybillService logiWaybillService;

    @Resource
    private ILogiWaybillGoodSourceService logiWaybillGoodSourceService;

    @Resource
    private ILogiProjectService logiProjectService;

    @Resource
    private ILogiSysDeptService logiSysDeptService;

    @Resource
    private ILogiGoodSourceService logiGoodSourceService;

    @Override
    public TableDataInfo<LogiCustomerBusStatisticsVo> customerStatisticsPage(LogiCustomerBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        PagePlus<LogiCustomer, LogiCustomerBusStatisticsVo> result = logiCustomerService.pageVo(PageUtils.buildPagePlus(bo, true), buildQueryWrapper(bo, completedWaybills), LogiCustomerBusStatisticsVo.class);
        List<LogiCustomerBusStatisticsVo> pageListVos = result.getRecordsVo();
        fillData(pageListVos, bo, completedWaybills);
        result.setRecordsVo(pageListVos);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiCustomerBusStatisticsVo> customerStatisticsList(LogiCustomerBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        List<LogiCustomerBusStatisticsVo> result = logiCustomerService.listVo(buildQueryWrapper(bo, completedWaybills), LogiCustomerBusStatisticsVo.class);
        fillData(result, bo, completedWaybills);
        return result;
    }

    @Override
    public TableDataInfo<LogiProjectBusStatisticsVo> projectStatisticsPage(LogiProjectBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        PagePlus<LogiProject, LogiProjectBusStatisticsVo> result = logiProjectService.pageVo(PageUtils.buildPagePlus(bo, true), buildQueryWrapper(bo, completedWaybills), LogiProjectBusStatisticsVo.class);
        List<LogiProjectBusStatisticsVo> pageListVos = result.getRecordsVo();
        fillData(pageListVos, bo, completedWaybills);
        result.setRecordsVo(pageListVos);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiProjectBusStatisticsVo> projectStatisticsList(LogiProjectBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        List<LogiProjectBusStatisticsVo> result = logiProjectService.listVo(buildQueryWrapper(bo, completedWaybills), LogiProjectBusStatisticsVo.class);
        fillData(result, bo, completedWaybills);
        return result;
    }

    @Override
    public TableDataInfo<LogiBranchBusStatisticsVo> branchStatisticsPage(LogiBranchBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        PagePlus<LogiSysDept, LogiBranchBusStatisticsVo> result = logiSysDeptService.pageVo(PageUtils.buildPagePlus(bo, true), buildQueryWrapper(bo, completedWaybills), LogiBranchBusStatisticsVo.class);
        List<LogiBranchBusStatisticsVo> pageListVos = result.getRecordsVo();
        fillData(pageListVos, bo, completedWaybills);
        result.setRecordsVo(pageListVos);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiBranchBusStatisticsVo> branchStatisticsList(LogiBranchBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        List<LogiBranchBusStatisticsVo> result = logiSysDeptService.listVo(buildQueryWrapper(bo, completedWaybills), LogiBranchBusStatisticsVo.class);
        fillData(result, bo, completedWaybills);
        return result;
    }

    @Override
    public TableDataInfo<LogiTransportBusStatisticsVo> transportStatisticsPage(LogiTransportBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        List<Long> waybillIds = completedWaybills.stream().map(LogiWaybill::getWaybillId).distinct().collect(Collectors.toList());
        List<LogiWaybillGoodSource> waybillgoodSourceList = logiWaybillGoodSourceService.getByWaybillIds(CollUtil.isEmpty(waybillIds) ? CollUtil.newArrayList(0L) : waybillIds);
        PagePlus<LogiGoodSource, LogiTransportBusStatisticsVo> result = logiGoodSourceService.pageVo(PageUtils.buildPagePlus(bo, true), buildQueryWrapper(bo, waybillgoodSourceList), LogiTransportBusStatisticsVo.class);
        List<LogiTransportBusStatisticsVo> pageListVos = result.getRecordsVo();
        fillData(pageListVos, bo, completedWaybills, waybillgoodSourceList);
        result.setRecordsVo(pageListVos);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiTransportBusStatisticsVo> transportStatisticsList(LogiTransportBusStatisticsQueryBo bo) {
        List<LogiWaybill> completedWaybills = logiWaybillService.getCompletedWaybills(bo.getDeptId(), bo.getStartDate(), bo.getEndDate());
        List<Long> waybillIds = completedWaybills.stream().map(LogiWaybill::getWaybillId).distinct().collect(Collectors.toList());
        List<LogiWaybillGoodSource> waybillgoodSourceList = logiWaybillGoodSourceService.getByWaybillIds(CollUtil.isEmpty(waybillIds) ? CollUtil.newArrayList(0L) : waybillIds);
        List<LogiTransportBusStatisticsVo> result = logiGoodSourceService.listVo(buildQueryWrapper(bo, waybillgoodSourceList), LogiTransportBusStatisticsVo.class);
        fillData(result, bo, completedWaybills, waybillgoodSourceList);
        return result;
    }

    /**
     * 组装查询条件 - 客户业务统计
     **/
    private Wrapper<LogiCustomer> buildQueryWrapper(LogiCustomerBusStatisticsQueryBo bo, List<LogiWaybill> completedWaybills) {
        LambdaQueryWrapper<LogiCustomer> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getCustomerName()), LogiCustomer::getCustomerName, bo.getCustomerName());
        // 客户id集合
        List<Long> customerIds = completedWaybills.stream().map(a -> bo.getCustomerType() == 2 ? a.getDeliveryId() : a.getShipId()).distinct().collect(Collectors.toList());
        lqw.in(LogiCustomer::getCustomerId, CollUtil.isEmpty(customerIds) ? CollUtil.newArrayList(0L) : customerIds);
        return lqw;
    }

    /**
     * 补充字段数据 - 客户业务统计
     **/
    private void fillData(List<LogiCustomerBusStatisticsVo> pageListVos, LogiCustomerBusStatisticsQueryBo bo, List<LogiWaybill> completedWaybills) {
        pageListVos.parallelStream().forEach(a -> {
            // 设置客户类型
            a.setCustomerType(bo.getCustomerType());
            // 查询符合条件已完成的运单
            List<LogiWaybill> waybillList = completedWaybills.stream().filter(b -> a.getCustomerType() == 2 ? a.getCustomerId().equals(b.getDeliveryId()) : a.getCustomerId().equals(b.getShipId())).collect(Collectors.toList());
            // 运单id集合
            List<Long> waybillIds = waybillList.stream().map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            // 货物明细
            List<LogiWaybillGoodSource> goodSourceList = logiWaybillGoodSourceService.getByWaybillIds(waybillIds);
            // 总出货量（吨）
            BigDecimal totalShipQuality = goodSourceList.stream().filter(b -> StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setTotalShipQuality(totalShipQuality);
            // 完成出货量（吨）
            List<Long> completedWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 0).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            BigDecimal finishShipQuality = goodSourceList.stream().filter(b -> completedWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setFinishShipQuality(finishShipQuality);
            // 关联运单数量
            a.setWaybillNum(waybillList.size());
            // 交易额（万元）
            BigDecimal tradeAmount = waybillList.stream().map(LogiWaybill::getPayableTotalFee).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setTradeAmount(tradeAmount);
            // 完成退货量（吨）
            List<Long> returnWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 1).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            BigDecimal finishReturnQuality = goodSourceList.stream().filter(b -> returnWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setFinishReturnQuality(finishReturnQuality);
            // 退货运单量
            a.setReturnWaybillNum(returnWaybillIds.size());
            // 退货交易金额（万元）
            BigDecimal returnTradeAmount = waybillList.stream().filter(b -> b.getRefund() == 1).map(LogiWaybill::getPayableTotalFee).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setReturnTradeAmount(returnTradeAmount);
            // 运单退货率
            a.setWaybillReturnRate(NumberUtil.formatPercent(NumberUtil.div(a.getReturnWaybillNum(), a.getWaybillNum()).doubleValue(), 2));
            // 时间范围
            if (ObjectUtil.isAllNotEmpty(bo.getStartDate(), bo.getEndDate())) {
                a.setTimeFrame(DateUtil.formatDate(DateUtil.parse(bo.getStartDate())) + " - " + DateUtil.formatDate(DateUtil.parse(bo.getEndDate())));
            } else {
                a.setTimeFrame("至今");
            }
        });
    }

    /**
     * 组装查询条件 - 项目业务统计
     **/
    private Wrapper<LogiProject> buildQueryWrapper(LogiProjectBusStatisticsQueryBo bo, List<LogiWaybill> completedWaybills) {
        LambdaQueryWrapper<LogiProject> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getProjectName()), LogiProject::getProjectName, bo.getProjectName());
        // 客户名称筛选
        if (StrUtil.isNotBlank(bo.getCustomerName())) {
            String existsSql = "select 1 from logi_customer where logi_customer.customer_id = logi_project.customer_id" +
                    " and logi_customer.customer_name like '%" + bo.getCustomerName() + "%'";
            lqw.exists(existsSql);
        }
        // 项目id集合
        List<Long> projectIds = completedWaybills.stream().map(LogiWaybill::getProjectId).distinct().collect(Collectors.toList());
        lqw.in(LogiProject::getId, CollUtil.isEmpty(projectIds) ? CollUtil.newArrayList(0L) : projectIds);
        return lqw;
    }

    /**
     * 补充字段数据 - 项目业务统计
     **/
    private void fillData(List<LogiProjectBusStatisticsVo> pageListVos, LogiProjectBusStatisticsQueryBo bo, List<LogiWaybill> completedWaybills) {
        pageListVos.parallelStream().forEach(a -> {
            // 设置所属客户名称
            LogiCustomer customer = logiCustomerService.getById(a.getCustomerId());
            if (ObjectUtil.isNotEmpty(customer)) {
                a.setCustomerName(customer.getCustomerName());
            }
            // 查询符合条件已完成的运单
            List<LogiWaybill> waybillList = completedWaybills.stream().filter(b -> a.getId().equals(b.getProjectId())).collect(Collectors.toList());
            // 运单id集合
            List<Long> waybillIds = waybillList.stream().map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            // 货物明细
            List<LogiWaybillGoodSource> goodSourceList = logiWaybillGoodSourceService.getByWaybillIds(waybillIds);
            // 完成出货量（吨）
            List<Long> completedWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 0).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            BigDecimal finishShipQuality = goodSourceList.stream().filter(b -> completedWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setFinishShipQuality(finishShipQuality);
            // 关联运单数量
            a.setWaybillNum(waybillList.size());
            // 交易额（万元）
            BigDecimal tradeAmount = waybillList.stream().map(LogiWaybill::getPayableTotalFee).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setTradeAmount(tradeAmount);
            // 完成退货量（吨）
            List<Long> returnWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 1).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            BigDecimal finishReturnQuality = goodSourceList.stream().filter(b -> returnWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setFinishReturnQuality(finishReturnQuality);
            // 退货运单量
            a.setReturnWaybillNum(returnWaybillIds.size());
            // 退货交易金额（万元）
            BigDecimal returnTradeAmount = waybillList.stream().filter(b -> b.getRefund() == 1).map(LogiWaybill::getPayableTotalFee).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setReturnTradeAmount(returnTradeAmount);
            // 运单退货率
            a.setWaybillReturnRate(NumberUtil.formatPercent(NumberUtil.div(a.getReturnWaybillNum(), a.getWaybillNum()).doubleValue(), 2));
            // 时间范围
            if (ObjectUtil.isAllNotEmpty(bo.getStartDate(), bo.getEndDate())) {
                a.setTimeFrame(DateUtil.formatDate(DateUtil.parse(bo.getStartDate())) + " - " + DateUtil.formatDate(DateUtil.parse(bo.getEndDate())));
            } else {
                a.setTimeFrame("至今");
            }
        });
    }

    /**
     * 组装查询条件 - 网点业务统计
     **/
    private Wrapper<LogiSysDept> buildQueryWrapper(LogiBranchBusStatisticsQueryBo bo, List<LogiWaybill> completedWaybills) {
        LambdaQueryWrapper<LogiSysDept> lqw = Wrappers.lambdaQuery();
        lqw.eq(LogiSysDept::getDeptType, DeptTypeEnum.BRANCH.getType());
        lqw.like(StrUtil.isNotBlank(bo.getDeptName()), LogiSysDept::getDeptName, bo.getDeptName());
        // 组织id集合
        List<Long> deptIds = completedWaybills.stream().map(LogiWaybill::getDeptId).distinct().collect(Collectors.toList());
        lqw.in(LogiSysDept::getDeptId, CollUtil.isEmpty(deptIds) ? CollUtil.newArrayList(0L) : deptIds);
        return lqw;
    }

    /**
     * 补充字段数据 - 网点业务统计
     **/
    private void fillData(List<LogiBranchBusStatisticsVo> pageListVos, LogiBranchBusStatisticsQueryBo bo, List<LogiWaybill> completedWaybills) {
        pageListVos.parallelStream().forEach(a -> {
            // 设置合作客户（只统计发货方）
            long customerNum = logiCustomerService.count(Wrappers.lambdaQuery(LogiCustomer.class)
                    .eq(LogiCustomer::getDeptId, a.getDeptId())
                    .exists("select 1 from logi_waybill where logi_waybill.ship_id = logi_customer.customer_id"));
            a.setCustomerNum(Math.toIntExact(customerNum));
            // 设置合作项目
            long projectNum = logiProjectService.count(Wrappers.lambdaQuery(LogiProject.class)
                    .eq(LogiProject::getDeptId, a.getDeptId()));
            a.setProjectNum(Math.toIntExact(projectNum));
            // 查询符合条件已完成的运单
            List<LogiWaybill> waybillList = completedWaybills.stream().filter(b -> a.getDeptId().equals(b.getDeptId())).collect(Collectors.toList());
            // 运单id集合
            List<Long> waybillIds = waybillList.stream().map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            // 货物明细
            List<LogiWaybillGoodSource> goodSourceList = logiWaybillGoodSourceService.getByWaybillIds(waybillIds);
            // 完成出货量（吨）
            List<Long> completedWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 0).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            BigDecimal finishShipQuality = goodSourceList.stream().filter(b -> completedWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setFinishShipQuality(finishShipQuality);
            // 关联运单数量
            a.setWaybillNum(waybillList.size());
            // 交易额（万元）
            BigDecimal tradeAmount = waybillList.stream().map(LogiWaybill::getPayableTotalFee).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setTradeAmount(tradeAmount);
            // 完成退货量（吨）
            List<Long> returnWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 1).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
            BigDecimal finishReturnQuality = goodSourceList.stream().filter(b -> returnWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setFinishReturnQuality(finishReturnQuality);
            // 退货运单量
            a.setReturnWaybillNum(returnWaybillIds.size());
            // 退货交易金额（万元）
            BigDecimal returnTradeAmount = waybillList.stream().filter(b -> b.getRefund() == 1).map(LogiWaybill::getPayableTotalFee).reduce(BigDecimal.ZERO, BigDecimal::add);
            a.setReturnTradeAmount(returnTradeAmount);
            // 运单退货率
            a.setWaybillReturnRate(NumberUtil.formatPercent(NumberUtil.div(a.getReturnWaybillNum(), a.getWaybillNum()).doubleValue(), 2));
            // 时间范围
            if (ObjectUtil.isAllNotEmpty(bo.getStartDate(), bo.getEndDate())) {
                a.setTimeFrame(DateUtil.formatDate(DateUtil.parse(bo.getStartDate())) + " - " + DateUtil.formatDate(DateUtil.parse(bo.getEndDate())));
            } else {
                a.setTimeFrame("至今");
            }
        });
    }

    /**
     * 组装查询条件 - 货物运输统计
     **/
    private Wrapper<LogiGoodSource> buildQueryWrapper(LogiTransportBusStatisticsQueryBo bo, List<LogiWaybillGoodSource> waybillgoodSourceList) {
        LambdaQueryWrapper<LogiGoodSource> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getGoodsName()), LogiGoodSource::getGoodsName, bo.getGoodsName());
        lqw.eq(ObjectUtil.isNotNull(bo.getGoodsType()), LogiGoodSource::getGoodsType, bo.getGoodsType());
        // 货号集合
        List<String> goodCodeList = waybillgoodSourceList.stream().map(LogiWaybillGoodSource::getGoodCode).distinct().collect(Collectors.toList());
        lqw.in(LogiGoodSource::getGoodCode, CollUtil.isEmpty(waybillgoodSourceList) ? CollUtil.newArrayList("") : goodCodeList);
        return lqw;
    }

    /**
     * 补充字段数据 - 货物运输统计
     **/
    private void fillData(List<LogiTransportBusStatisticsVo> pageListVos, LogiTransportBusStatisticsQueryBo bo, List<LogiWaybill> completedWaybills, List<LogiWaybillGoodSource> waybillgoodSourceList) {
        Map<String, List<LogiWaybillGoodSource>> waybillgoodSourceMap = waybillgoodSourceList.stream().collect(Collectors.groupingBy(LogiWaybillGoodSource::getGoodCode));
        pageListVos.parallelStream().forEach(a -> {
            // 货物明细
            List<LogiWaybillGoodSource> goodSourceList = waybillgoodSourceMap.get(a.getGoodCode());
            // 已完成运单数值统计
            if (CollUtil.isNotEmpty(goodSourceList)) {
                // 查询符合条件已完成的运单
                List<Long> waybillIds = goodSourceList.stream().map(LogiWaybillGoodSource::getWaybillId).distinct().collect(Collectors.toList());
                List<LogiWaybill> waybillList = completedWaybills.stream().filter(b -> waybillIds.contains(b.getWaybillId())).collect(Collectors.toList());
                // 完成出货量（吨）
                List<Long> completedWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 0).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
                BigDecimal finishShipQuality = goodSourceList.stream().filter(b -> completedWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
                a.setFinishShipQuality(finishShipQuality);
                // 关联运单数量
                a.setWaybillNum(waybillList.size());
                // 交易额（万元）
                BigDecimal tradeAmount = goodSourceList.stream().map(b -> new BigDecimal(b.getCarriageFee())).reduce(BigDecimal.ZERO, BigDecimal::add);
                a.setTradeAmount(tradeAmount);
                // 完成退货量（吨）
                List<Long> returnWaybillIds = waybillList.stream().filter(b -> b.getRefund() == 1).map(LogiWaybill::getWaybillId).collect(Collectors.toList());
                BigDecimal finishReturnQuality = goodSourceList.stream().filter(b -> returnWaybillIds.contains(b.getWaybillId()) && StrUtil.isNotBlank(b.getWeight())).map(b -> new BigDecimal(b.getWeight())).reduce(BigDecimal.ZERO, BigDecimal::add);
                a.setFinishReturnQuality(finishReturnQuality);
                // 退货运单量
                a.setReturnWaybillNum(returnWaybillIds.size());
                // 退货交易金额（万元）
                BigDecimal returnTradeAmount = goodSourceList.stream().filter(b -> returnWaybillIds.contains(b.getWaybillId())).map(b -> new BigDecimal(b.getCarriageFee())).reduce(BigDecimal.ZERO, BigDecimal::add);
                a.setReturnTradeAmount(returnTradeAmount);
                // 运单退货率
                a.setWaybillReturnRate(NumberUtil.formatPercent(NumberUtil.div(a.getReturnWaybillNum(), a.getWaybillNum()).doubleValue(), 2));
            }
            // 时间范围
            if (ObjectUtil.isAllNotEmpty(bo.getStartDate(), bo.getEndDate())) {
                a.setTimeFrame(DateUtil.formatDate(DateUtil.parse(bo.getStartDate())) + " - " + DateUtil.formatDate(DateUtil.parse(bo.getEndDate())));
            } else {
                a.setTimeFrame("至今");
            }
        });
    }
}
